package ints

import (
	"github.com/gin-gonic/gin"
	"github.com/pkg/errors"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/app/ginsrv/api/base"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/common"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/interactiond"
)

func createTypCtrl(d core.CmsDomain) *typCtrl {
	return &typCtrl{
		BaseContrl: base.BaseContrl{
			Domain: d,
		},
		tar: d.Interaction().TypeAggregateRoot(),
	}
}

type typCtrl struct {
	base.BaseContrl
	tar interactiond.TypeAggregateRoot
}

// 获取query中的信息组查询参数
func (c typCtrl) getTypSearch(ctx *gin.Context) (result interactiond.TypeSearch, err error) {
	result.Key = ctx.DefaultQuery("key", "")
	ss := c.GetIntArrayByQuery(ctx, "status", nil)
	if len(ss) > 0 {
		for _, v := range ss {
			result.Status = append(result.Status, interactiond.ITStatus(v))
		}
	}
	return
}
func (c typCtrl) getTypePageList(ctx *gin.Context) {

	page := c.GetPageInfo(ctx, common.PageModeNum)
	dctx := c.DDDContext(ctx)

	sch, err := c.getTypSearch(ctx)
	if err != nil {
		c.ErrBadRequestByBind(ctx, 1, err)
		return
	}
	pr, cs, err := c.tar.QueryPage(dctx, sch, page)
	if err != nil {
		c.ErrServerError(ctx, 1, "查找信息互动类型失败", errors.Wrap(err, "查找互动类型失败."))
		return
	}
	if cs == nil {
		cs = make([]interactiond.TypeAggregate, 0)
	}
	c.SuccessPage(ctx, page, pr, cs)
}

func (c typCtrl) getTypeAll(ctx *gin.Context) {
	dctx := c.DDDContext(ctx)

	cs, err := c.tar.All(dctx)
	if err != nil {
		c.ErrServerError(ctx, 1, "查找信息互动类型失败", errors.Wrap(err, "查找互动类型失败."))
		return
	}
	if cs == nil {
		cs = make([]interactiond.TypeAggregate, 0)
	}
	c.Success(ctx, cs)
}

// ReqTypeDesc 新增信息组请求
type ReqTypeDesc struct {
	Code     string              `json:"code" bind:"required,max=30"`         // 编码
	Name     string              `json:"name" bind:"required,max=100"`        // 名称
	Mode     interactiond.ITMode `json:"mode" bind:"required,eq=0|eq=1|eq=2"` // 用户模式模式 0 累计计数 1 求平均值 2 一次记录，取最后一次的值
	IsPublic int                 `json:"is_public" bind:"required,eq=0|eq=1"` // 是否开放 0 不开放，1公开
	IsAgv    bool                `json:"is_agv" bind:"required"`              // 是否启用平均值
	Max      int                 `json:"max" bind:"required"`                 // 最大分数
	Min      int                 `json:"min" bind:"required"`                 // 最小分数
	//Status   interactiond.ITStatus `json:"status"`                             // 状态 0 初始化<br/> -1 删除 <br/>1 发布
}

// To 转换为 groupd.TypeDesc
func (r ReqTypeDesc) To() interactiond.TypeDesc {
	return interactiond.TypeDesc{
		Code:     r.Code,
		Name:     r.Name,
		Mode:     r.Mode,
		IsPublic: r.IsPublic,
		Max:      r.Max,
		Min:      r.Min,
		IsAgv:    r.IsAgv,
	}
}
func (c typCtrl) add(ctx *gin.Context) {
	var req ReqTypeDesc

	if err := ctx.BindJSON(&req); err != nil {
		c.ErrBadRequestByBind(ctx, 1, err)
		return
	}
	dctx := c.DDDContext(ctx)
	desc := req.To()

	ok, err := c.tar.ExistNameByCode(dctx, desc.Name, "")
	if err != nil {
		c.ErrServerError(ctx, 2, "保存失败", errors.Wrap(err, "查询互动类型名称是否存在失败．"))
		return
	}
	if ok {
		c.ErrBadRequest(ctx, 3, "互动类型名称已经存在")
		return
	}
	t, err := c.tar.GetType(dctx, desc.Code)
	if err != nil {
		c.ErrServerError(ctx, 4, "保存失败", errors.Wrap(err, "查询互动类型编号是否存在失败．"))
		return
	}
	if t != nil {
		c.ErrBadRequest(ctx, 5, "互动类型编号已经存在")
		return
	}
	err = c.tar.CreType(dctx, desc)
	if err != nil {
		c.ErrServerError(ctx, 6, "新增失败", errors.Wrap(err, "新增互动类型失败："))
		return
	}
	c.Success(ctx, nil)
}
func (c typCtrl) getType(ctx *gin.Context) {
	code := ctx.Param("code")
	if code == "" {
		c.ErrBadRequest(ctx, 1, "请求参数错误", nil)
		return
	}
	dctx := c.DDDContext(ctx)
	ta, err := c.tar.GetType(dctx, code)
	if err != nil {
		c.ErrServerError(ctx, 2, "查找互动类型失败", errors.Wrapf(err, "检测互动类型(%v)是否存在失败：%v", code, err))
		return
	}
	if ta == nil {
		c.ErrNotFound(ctx, 3, "互动类型不存在", nil)
		return
	}
	c.Success(ctx, ta)
}
func (c typCtrl) delete(ctx *gin.Context) {
	code := ctx.Param("code")
	dctx := c.DDDContext(ctx)
	if code == "" {
		c.ErrBadRequest(ctx, 1, "请求参数错误", nil)
		return
	}
	ta, err := c.tar.GetType(dctx, code)
	if err != nil {
		c.ErrServerError(ctx, 2, "查找互动类型失败", errors.Wrapf(err, "检测互动类型(%v)是否存在失败：%v", code, err))
		return
	}
	if ta == nil {
		c.ErrNotFound(ctx, 3, "互动类型不存在", nil)
		return
	}
	if ta.Status == interactiond.ITStatusLock {
		c.ErrBadRequest(ctx, 4, "已锁定不能删除", nil)
		return
	}
	if err = ta.Delete(dctx); err != nil {
		c.ErrServerError(ctx, 5, "删除失败", errors.Wrapf(err, "删除互动类型(%v)失败", code))
		return
	}
	c.Success(ctx, nil)
}
func (c typCtrl) recover(ctx *gin.Context) {
	code := ctx.Param("code")
	dctx := c.DDDContext(ctx)
	if code == "" {
		c.ErrBadRequest(ctx, 1, "请求参数错误", nil)
		return
	}
	ta, err := c.tar.GetType(dctx, code)
	if err != nil {
		c.ErrServerError(ctx, 2, "查找互动类型失败", errors.Wrapf(err, "检测互动类型(%v)是否存在失败：%v", code, err))
		return
	}
	if ta == nil {
		c.ErrNotFound(ctx, 3, "互动类型不存在", nil)
		return
	}
	if ta.Status != interactiond.ITStatusDel {
		c.ErrBadRequest(ctx, 4, "不是删除状态不能恢复", nil)
		return
	}
	if err = ta.Recover(dctx); err != nil {
		c.ErrServerError(ctx, 5, "恢复失败", errors.Wrapf(err, "恢复互动类型(%v)失败", code))
		return
	}
	c.Success(ctx, nil)
}

func (c typCtrl) lock(ctx *gin.Context) {
	code := ctx.Param("code")
	dctx := c.DDDContext(ctx)
	if code == "" {
		c.ErrBadRequest(ctx, 1, "请求参数错误", nil)
		return
	}
	ta, err := c.tar.GetType(dctx, code)
	if err != nil {
		c.ErrServerError(ctx, 2, "查找互动类型失败", errors.Wrapf(err, "检测互动类型(%v)是否存在失败：%v", code, err))
		return
	}
	if ta == nil {
		c.ErrNotFound(ctx, 3, "互动类型不存在", nil)
		return
	}
	if ta.Status != interactiond.ITStatusInit {
		c.ErrBadRequest(ctx, 4, "不是初始化状态不能锁定", nil)
		return
	}
	if err = ta.Lock(dctx); err != nil {
		c.ErrServerError(ctx, 5, "锁定失败", errors.Wrapf(err, "锁定互动类型(%v)失败", code))
		return
	}
	c.Success(ctx, nil)
}

func (c typCtrl) unlock(ctx *gin.Context) {
	code := ctx.Param("code")
	dctx := c.DDDContext(ctx)
	if code == "" {
		c.ErrBadRequest(ctx, 1, "请求参数错误", nil)
		return
	}
	ta, err := c.tar.GetType(dctx, code)
	if err != nil {
		c.ErrServerError(ctx, 2, "查找互动类型失败", errors.Wrapf(err, "检测互动类型(%v)是否存在失败：%v", code, err))
		return
	}
	if ta == nil {
		c.ErrNotFound(ctx, 3, "互动类型不存在", nil)
		return
	}
	if ta.Status != interactiond.ITStatusLock {
		c.ErrBadRequest(ctx, 4, "不是锁定状态不能解锁", nil)
		return
	}
	if err = ta.Unlock(dctx); err != nil {
		c.ErrServerError(ctx, 5, "解锁失败", errors.Wrapf(err, "解锁互动类型(%v)失败", code))
		return
	}
	c.Success(ctx, nil)
}
func (c typCtrl) destroy(ctx *gin.Context) {
	code := ctx.Param("code")
	dctx := c.DDDContext(ctx)
	if code == "" {
		c.ErrBadRequest(ctx, 1, "请求参数错误", nil)
		return
	}
	ta, err := c.tar.GetType(dctx, code)
	if err != nil {
		c.ErrServerError(ctx, 2, "查找互动类型失败", errors.Wrapf(err, "检测互动类型(%v)是否存在失败：%v", code, err))
		return
	}
	if ta == nil {
		c.ErrNotFound(ctx, 3, "互动类型不存在", nil)
		return
	}
	if ta.Status != interactiond.ITStatusDel {
		c.ErrBadRequest(ctx, 4, "不是删除状态不能彻底删除", nil)
		return
	}
	if err = ta.Destroy(dctx); err != nil {
		c.ErrServerError(ctx, 5, "彻底删除失败", errors.Wrapf(err, "彻底删除互动类型(%v)失败", code))
		return
	}
	c.Success(ctx, nil)
}
func (c typCtrl) updateDesc(ctx *gin.Context) {
	code := ctx.Param("code")
	if code == "" {
		c.ErrBadRequest(ctx, 1, "请求参数错误", nil)
		return
	}
	var req ReqTypeDesc
	if err := ctx.BindJSON(&req); err != nil {
		c.ErrBadRequestByBind(ctx, 1, err)
		return
	}
	dctx := c.DDDContext(ctx)
	desc := req.To()

	ta, err := c.tar.GetType(dctx, code)
	if err != nil {
		c.ErrServerError(ctx, 2, "查找互动类型失败", errors.Wrapf(err, "检测互动类型(%v)是否存在失败：%v", code, err))
		return
	}
	if ta == nil {
		c.ErrNotFound(ctx, 3, "互动类型不存在", nil)
		return
	}
	if ta.Status != interactiond.ITStatusInit {
		c.ErrBadRequest(ctx, 4, "不是初始化状态不能编辑", nil)
		return
	}
	if err = ta.UpdateDesc(dctx, &desc); err != nil {
		c.ErrServerError(ctx, 5, "保存失败", errors.Wrapf(err, "保存互动类型(%v)失败", code))
		return
	}
	c.Success(ctx, nil)
}
